package com.example.gobang.game;

import com.example.gobang.model.User;
import com.example.gobang.model.UserMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.UUID;

/**
 * author: hyacinth
 * Date: 2023/5/26
 */
@Component
@Data
public class Room {


    private String roomId;
    private User user1;
    private User user2;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private RoomManager roomManager;

    private UserMapper userMapper;
    private int whiteUser;

    public Room() {
        // 使用 UUID 作为房间id
        roomId = UUID.randomUUID().toString();
        /*onlineUserManager = GobangApplication.context.getBean(OnlineUserManager.class);
        roomManager = GobangApplication.context.getBean(RoomManager.class);
        userMapper = GobangApplication.context.getBean(UserMapper.class)*/
        ;
    }

    //     表示棋盘
//     0: 未落子
//     1: user1的落子
//     2: user2的落子
    private int[][] board = new int[15][15];

    /**
     * 处理一次落子请求
     *
     * @param jsonString
     */
    public void putChess(String jsonString) throws IOException {
        //  1. 记录当前落子的位置
        GameRequest request = objectMapper.readValue(jsonString, GameRequest.class);
        GameResponse response = new GameResponse();
        // 当前落子是玩家1还是玩家2
        int chess = request.getUserId() == user1.getUserId() ? 1 : 2;
        int row = request.getRow();
        int col = request.getCol();
        if (board[row][col] != 0) {
            System.out.println("当前位置已经有棋子了!");
            return;
        }
        board[row][col] = chess;
        printBoard(board);
        // 2. 进行胜负的判定
        int winner = checkWinner(row, col, chess);
        // 3. 给客户端返回响应
        response.setMessage("putChess");
        response.setUserId(request.getUserId());
        response.setCol(col);
        response.setRow(row);
        response.setWinner(winner);

        WebSocketSession session1 = onlineUserManager.getSessionFromGameRoom(user1.getUserId());
        WebSocketSession session2 = onlineUserManager.getSessionFromGameRoom(user2.getUserId());
        if (session1 == null) {
            response.setWinner(user2.getUserId());
            System.out.println("玩家掉线");
        }
        if (session2 == null) {
            response.setWinner(user1.getUserId());
            System.out.println("玩家掉线");
        }
        if (session1 != null) {
            session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
        if (session2 != null) {
            session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

        // 4.如果当前胜负已分,游戏房间就没用了
        if (response.getWinner() != 0) {
            System.out.println("游戏胜负已分!");
            int winUserId = response.getWinner();
            int loseUserId = response.getWinner() == user1.getUserId() ? user2.getUserId() : user1.getUserId();
            userMapper.UserWin(winUserId);
            userMapper.UserLose(loseUserId);
            roomManager.remove(roomId, user1.getUserId(), user2.getUserId());
        }
    }

    /**
     * 胜负判定
     *
     * @param row
     * @param col
     * @return
     */
    private int checkWinner(int row, int col, int chess) {
        // 检查所有的行
        for (int i = col - 4; i <= col; i++) {
            try {
                if (board[row][i] == chess
                        && board[row][i + 1] == chess
                        && board[row][i + 2] == chess
                        && board[row][i + 3] == chess
                        && board[row][i + 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }

        // 检查所有列
        for (int i = row - 4; i <= row; i++) {
            try {
                if (board[i][col] == chess
                        && board[i + 1][col] == chess
                        && board[i + 2][col] == chess
                        && board[i + 3][col] == chess
                        && board[i + 4][col] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }

        // 左对角线
        for (int i = row - 4, j = col - 4; i <= row; i++, j++) {
            try {
                if (board[i][j] == chess
                        && board[i + 1][j + 1] == chess
                        && board[i + 2][j + 2] == chess
                        && board[i + 3][j + 3] == chess
                        && board[i + 4][j + 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }
        // 右对角线
        for (int i = row - 4, j = col + 4; i <= row; i++, j--) {
            try {
                if (board[i][j] == chess
                        && board[i + 1][j - 1] == chess
                        && board[i + 2][j - 2] == chess
                        && board[i + 3][j - 3] == chess
                        && board[i + 4][j - 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }
        // 胜负未分

        return 0;
    }

    private final int Max_row = 15;
    private final int Max_col = 15;

    private void printBoard(int[][] board) {
        System.out.println("roomId: " + roomId);
        System.out.println("------打印棋盘信息------");
        for (int i = 0; i < Max_row; i++) {
            for (int j = 0; j < Max_col; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("---------------------");
    }
}
